package com.zx.mes.hyl.singleton;

import lombok.extern.java.Log;
import org.junit.Test;

import java.io.*;

/**
 * 单例模式测试
 *
 * @author 华云龙
 * @date 2018-9-3
 */
@Log
public class SingletonTest {

    /**
     * 非多线程
     *
     * @throws InterruptedException
     */
    @Test
    public void test() {

        Thread t1 = new Thread(new T());
        Thread t2 = new Thread(new T());

        t1.start();
        t2.start();

        System.out.println("执行测试");
    }

    @Test
    public void test2() {
        LazyDoubleCheckSingleton instance = LazyDoubleCheckSingleton.getInstance();
        System.out.println(instance);
    }

    @Test
    public void test3() {
        StaticInnerSingleton staticInnerSingleton = StaticInnerSingleton.getInstance();
    }

    /**
     * 静态内部类多线程单例测试
     */
    @Test
    public void test4() throws InterruptedException {
        new Thread(new T2()).start();
        new Thread(new T2()).start();

        Thread.sleep(1000);
    }

    /**
     * 对象初使化的顺序
     * 08:38:58.934 [main] INFO com.zx.mes.hyl.singleton.StaticInnerSingleton - 静态代码块
     * 08:38:58.934 [main] INFO com.zx.mes.hyl.singleton.StaticInnerSingleton - 一般代码块
     * 08:38:58.934 [main] INFO com.zx.mes.hyl.singleton.StaticInnerSingleton - 空参实例化
     */
    @Test
    public void test5() {
        StaticInnerSingleton instance = StaticInnerSingleton.getInstance();
        log.info(instance.toString());
    }

    /**
     * 序例化破坏单例模式
     */
    @Test
    public void test6() throws IOException, ClassNotFoundException {
        LazyDoubleCheckSerializableSingleton instance = LazyDoubleCheckSerializableSingleton.getInstance();
        log.info("创建对象:" + instance.toString());
        /// 对象读取
        ByteArrayOutputStream b = new ByteArrayOutputStream(1024);
        ObjectOutput output = new ObjectOutputStream(b);
        output.writeObject(instance);

        /// 对象读入
        ObjectInput input = new ObjectInputStream(new ByteArrayInputStream(b.toByteArray()));
        LazyDoubleCheckSerializableSingleton o = (LazyDoubleCheckSerializableSingleton) input.readObject();
        log.info("序例化对象:" + (o).toString());

    }

    /**
     * 如何保证单例不被序列化破坏
     */
    @Test
    public void test7() throws IOException, ClassNotFoundException {
        LazyDoubleCheckSerializableSingleton2 instance = LazyDoubleCheckSerializableSingleton2.getInstance();

        ByteArrayOutputStream b = new ByteArrayOutputStream(1024);
        ObjectOutput output = new ObjectOutputStream(b);
        output.writeObject(instance);

        ObjectInput input = new ObjectInputStream(new ByteArrayInputStream(b.toByteArray()));
        LazyDoubleCheckSerializableSingleton2 o = (LazyDoubleCheckSerializableSingleton2) input.readObject();
        log.info("创建对象:" + instance.toString() + "   序例化对象:" + (o).toString());


    }
}
